package EA.testproblems;
import EA.*;

/**

<table border="0" cellpadding="2" cellspacing="0">
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem description</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top" width="200"><b>Name:</b></td>
  <td valign="top">Schaffer F7 - tilted</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Nickname:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Intended usage:</b></td>
  <td valign="top">Harder test for multiobjective optimization. The difference
  between the Schaffer F7 and this function is that this has actual optimums
  and not rings with same value.
</td>
</tr>

<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem details</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Function:</b></td>
  <td valign="top">(x<sup>2</sup> + y<sup>2</sup>)<sup>0.25</sup>[sin<sup>2</sup>(50(x<sup>2</sup> + y<sup>2</sup>)<sup>0.1</sup>) + 1.0] + 0.05*x + 0.02*y
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Plots:</b></td>
  <td valign="top"><img src="../../images/testproblems/schaffertiltedf7.gif">&nbsp;&nbsp;
<img src="../../images/testproblems/schaffertiltedf7_contour.gif"></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Ranges:</b></td>
  <td valign="top">x = [-100:100]&nbsp;&nbsp;y = [-100:100] </td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Type:</b></td>
  <td valign="top">Minimization</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of maximas:</b></td>
  <td valign="top">?</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of minimas:</b></td>
  <td valign="top">More than 1</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum radius:</b></td>
  <td valign="top">0.1
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum descriptions:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Known optimums:</b></td>
  <td valign="top"><br><font size=1>Capital letters 
means that the precise optimum is known, lowercase letters is the best known 
so far.</font></td>
</tr>
<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Plotting details</b></td>
</tr>

<tr bgcolor="#e0e0e0">
  <td valign="top"><b>GNUPlot code:</b></td>
  <td valign="top">
  set hidden3d<br>
  set isosamples 40<br>
  set view 70,15<br>
  splot [-100:100] [-100:100] ((x*x + y*y)**0.25)*(sin(50*(x*x + y*y)**0.1)**2 + 1.0) + 0.05*x + 0.02*y
</td>

</tr>

</table>

*/
public class SchafferTiltedF7 extends NumericalProblem
{

  // Easier way to build max
  private double[][] lmax =  {{4.189748612, 1.675899445}, 
			      {6.533523154, 2.613409262}, 
			      {8.045665268, 3.218266107}, 
			      {1.978158703, .7912634812},
			      {1.117448986, .4469795943}, 
			      {9.825733197, 3.930293279}};

  private double[][] lmin =  {{0,0},
			      {-5.846957415, -2.338782966}, 
			      {-1.715171147, -.6860684586}, 
			      {-8.873127799, -3.549251120}, 
			      {-7.234232490, -2.893692996}, 
			      {-4.681151049, -1.872460419}, 
			      {-2.905783734, -1.162313493}, 
			      {-1.288495657, -.5153982627},
			      {-.9512870906, -.3805148362},
			      {-.4875443757, -.1950177503},
			      {-.3364042617, -.1345617047}, 
			      {-.2253007735, -.9012030941e-1},
			      {-.1456968174, -.5827872696e-1},
			      {-.9036513356e-1, -.3614605343e-1},
			      {-.5327912170e-1, -.2131164868e-1},
			      {.4106155447e-1, .1642462179e-1},
			      {-.2950366969e-1, -.1180146788e-1},
			      {-.1508598546e-1, -.6034394186e-2},
			      {-.2769366385e-2, -.1107746554e-2}};

  public SchafferTiltedF7()
    {
      super();

      double[] optimums;

      name = "Schaffer Tilted F7";
      objectivefunction = new NumericalFitness(){
	      public double Fitness_calcFitness_inner(double[] realpos)
	      {
		  return (Math.pow((realpos[0]*realpos[0] + realpos[1]*realpos[1]),0.25))*(Math.pow(Math.sin(50*Math.pow((realpos[0]*realpos[0] + realpos[1]*realpos[1]),0.1)),2) + 1.0) + 0.05*realpos[0] + 0.02*realpos[1];

	      };
	  };

      dimensions = 2;
      ismaximization = false;
      optimumradius = 0.1;

      intervals = new Interval[2];
      intervals[0] = new Interval(-100, 100);
      intervals[1] = new Interval(-100, 100);

      // Set up known maximas
      knownmaxima = new NumericalOptimum[lmax.length];

      for (int i=0;i<lmax.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmax[i][0];
	optimums[1] = lmax[i][1];
	knownmaxima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), true, false, i);
      }

      // Set up known minimas
      knownminima = new NumericalOptimum[lmin.length];

      for (int i=0;i<lmin.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmin[i][0];
	optimums[1] = lmin[i][1];
	knownminima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), false, true, i);
      }
    }
}
